home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
comm
/
net
/
dnet2_10_13.lha
/
DNet
/
Amiga
/
Sourcen.lha
/
dnet
/
packet.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-14
|
6KB
|
354 lines
/*
* PACKET.C
*/
#include "dnet.h"
void BuildPacket();
#define Ascize(foo) (((foo) & 0x3F) | 0x40)
ubyte RxTmp[MAXPACKET];
void
BuildDataPacket(pkt, win, dbuf, actlen)
PKT *pkt;
ubyte win;
ubyte *dbuf;
uword actlen;
{
ubyte *ptr;
ubyte *pend;
ubyte range = 0;
static ubyte BadCtl[32] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 1, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1
};
ptr = dbuf;
pend= dbuf + actlen;
while (ptr < pend) {
if (*ptr < 0x20 && BadCtl[*ptr])
range |= 1;
if (*ptr >= 0x80)
range |= 2;
++ptr;
}
if (Mode7 && range) {
uword buflen = Expand6(dbuf, pkt->data, actlen);
BuildPacket(pkt, PKCMD_WRITE6, win, pkt->data, actlen, buflen);
} else {
if (Mode7 || (range & 2)) {
BuildPacket(pkt, PKCMD_WRITE, win, dbuf, actlen, actlen);
} else {
uword buflen = Compress7(dbuf, pkt->data, actlen);
BuildPacket(pkt, PKCMD_WRITE7, win, pkt->data, actlen, buflen);
}
}
}
PKT *
BuildRestartAckPacket(dbuf, bytes)
ubyte *dbuf;
ubyte bytes;
{
static PKT pkt;
BuildPacket(&pkt, PKCMD_ACKRSTART, 0, dbuf, bytes, bytes);
return(&pkt);
}
void
BuildPacket(pkt, ctl, win, dbuf, actlen, buflen)
PKT *pkt;
ubyte ctl;
ubyte *dbuf;
uword actlen;
uword buflen;
{
pkt->buflen = buflen;
pkt->sync = SYNC;
pkt->ctl = ctl | win;
pkt->cchk = Ascize((pkt->sync << 1) ^ pkt->ctl);
if (actlen) {
uword chk = chkbuf(dbuf, buflen);
ubyte dchkh = chk >> 8;
ubyte dchkl = chk;
pkt->lenh = Ascize(actlen >> 6);
pkt->lenl = Ascize(actlen);
pkt->dchkh= Ascize(dchkh);
pkt->dchkl= Ascize(dchkl);
if (dbuf != pkt->data)
BMov(dbuf, pkt->data, buflen);
}
}
void
WritePacket(pkt)
PKT *pkt;
{
if (DDebug)
printf("SEND-PACKET %02x %d\n", pkt->ctl, pkt->buflen);
if (pkt->ctl == PKCMD_WRITE)
++Packets8Out;
if (pkt->ctl == PKCMD_WRITE6)
++Packets6Out;
if (pkt->ctl == PKCMD_WRITE7)
++Packets7Out;
if (pkt->buflen)
NetWrite(&pkt->sync, 7 + pkt->buflen);
else
NetWrite(&pkt->sync, 3);
}
void
WriteCtlPacket(ctl, win)
{
static CTLPKT pkt;
NetWrite(NULL, 0);
BuildPacket(&pkt, ctl, win, NULL, 0, 0);
WritePacket(&pkt);
}
void
WriteNak(win)
{
WriteCtlPacket(PKCMD_NAK, win);
}
void
WriteAck(win)
{
WriteCtlPacket(PKCMD_ACK, win);
}
void
WriteChk(win)
{
WriteCtlPacket(PKCMD_CHECK, win);
}
void
WriteRestart()
{
WriteCtlPacket(PKCMD_RESTART, 0);
}
/*
* RECEIVE A PACKET
*/
int
RecvPacket(ptr, len)
ubyte *ptr;
long len;
{
static uword ActLen; /* actual # bytes after decoding */
static uword BufLen; /* length of input data buffer */
static uword DBLen; /* # bytes already in i.d.buf */
static ubyte RState;
static PKT Pkt;
ubyte *dptr;
short expect;
if (ptr == NULL) {
RState = 0;
return(3);
}
while (len) {
switch(RState) {
case 0:
--len;
Pkt.sync = *ptr++;
if (Pkt.sync == SYNC)
++RState;
break;
case 1: /* CTL */
--len;
Pkt.ctl = *ptr++;
if (Pkt.ctl < 0x20 || Pkt.ctl > 0x7F) {
RState = 0;
break;
}
++RState;
break;
case 2: /* CCHK */
--len;
Pkt.cchk = *ptr++;
if (Ascize((SYNC<<1) ^ Pkt.ctl) != Pkt.cchk) {
RState = 0;
break;
}
switch(Pkt.ctl & PKF_MASK) {
case PKCMD_ACKRSTART:
case PKCMD_WRITE:
case PKCMD_WRITE6:
case PKCMD_WRITE7:
++RState;
break;
default:
do_cmd(Pkt.ctl, NULL, 0);
RState = 0;
break;
}
break;
case 3: /* LENH */
--len;
Pkt.lenh = *ptr++;
++RState;
if (Pkt.lenh < 0x20 || Pkt.lenh > 0x7F)
RState = 0;
break;
case 4: /* LENL */
--len;
Pkt.lenl = *ptr++;
if (Pkt.lenl < 0x20 || Pkt.lenl > 0x7F) {
RState = 0;
break;
}
++RState;
ActLen = ((Pkt.lenh & 0x3F) << 6) | (Pkt.lenl & 0x3F);
DBLen = 0;
switch(Pkt.ctl & PKF_MASK) {
case PKCMD_ACKRSTART:
case PKCMD_WRITE:
BufLen = ActLen;
break;
case PKCMD_WRITE6:
BufLen = (ActLen * 8 + 5) / 6;
break;
case PKCMD_WRITE7:
BufLen = (ActLen * 7 + 7) / 8;
break;
default:
puts("BaD");
break;
}
if (ActLen > MAXPKT || BufLen > MAXPACKET) {
if (PDebug || DDebug)
printf("Packet Length Error %d %d\n", ActLen, BufLen);
RState = 0;
}
break;
case 5: /* DChkH */
--len;
Pkt.dchkh = *ptr++;
++RState;
if (Pkt.dchkh < 0x20 || Pkt.dchkh > 0x7F)
RState = 0;
break;
case 6: /* DCHKL */
--len;
Pkt.dchkl = *ptr++;
++RState;
if (Pkt.dchkl < 0x20 || Pkt.dchkl > 0x7F)
RState = 0;
break;
case 7: /* -DATA- */
if (DBLen + len < BufLen) { /* not enough */
BMov(ptr, Pkt.data + DBLen, len);
DBLen += len;
len = 0;
break;
}
/*
* Enough data, check chk
*/
BMov(ptr, Pkt.data + DBLen, BufLen - DBLen);
len -= BufLen - DBLen;
ptr += BufLen - DBLen;
{
uword chk;
ubyte chkh;
ubyte chkl;
chk = chkbuf(Pkt.data, BufLen);
chkh = Ascize(chk >> 8);
chkl = Ascize(chk);
if (Pkt.dchkh != chkh || Pkt.dchkl != chkl) {
printf("Chksum failure %02x %02x %02x %02x\n",
Pkt.dchkh, chkh, Pkt.dchkl, chkl
);
RState = 0;
break;
}
}
switch(Pkt.ctl & PKF_MASK) {
case PKCMD_ACKRSTART:
dptr = Pkt.data;
break;
case PKCMD_WRITE:
dptr = Pkt.data;
++Packets8In;
break;
case PKCMD_WRITE6:
UnExpand6(Pkt.data, RxTmp, ActLen);
dptr = RxTmp;
++Packets6In;
break;
case PKCMD_WRITE7:
UnCompress7(Pkt.data, RxTmp, ActLen);
dptr = RxTmp;
++Packets7In;
break;
default:
puts("BaD2");
dptr = Pkt.data;
break;
}
do_cmd(Pkt.ctl, dptr, ActLen);
RState = 0;
break;
}
}
{
static short ExpAry[] = { 3, 2, 1, 4, 3, 2, 1, 0 };
expect = ExpAry[RState];
if (RState == 7)
expect = BufLen - DBLen;
}
if (Rto_act) {
AbortIO((IOR *)&Rto);
WaitIO((IOR *)&Rto);
Rto_act = 0;
}
if (RState == 7) {
Rto.tr_time.tv_secs = 8;
Rto.tr_time.tv_micro= 0;
SendIO((IOR *)&Rto);
Rto_act = 1;
}
do_cmd((uword)-1, NULL, 0);
return((int)expect);
}